package com.ailanyin.common.service;

import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * 自定义Redis接口
 *
 * @author ailanyin
 * @version 1.0
 * @since 2021/10/2 0002 下午 17:41
 */
public interface RedisService {

    /**
     * 保存为 Set
     *
     * @param key   key
     * @param value value
     * @param time  存活时间 单位秒
     */
    void set(String key, Object value, long time);

    /**
     * 保存为 Set, 永久
     *
     * @param key   key
     * @param value value
     */
    void set(String key, Object value);

    /**
     * 通过 key 获取值
     *
     * @param key key
     * @return Object
     */
    Object get(String key);

    /**
     * 删除 key
     *
     * @param key key
     * @return Boolean
     */
    Boolean del(String key);


    /**
     * 设置过期时间
     *
     * @param key  key
     * @param time 存活时间 单位秒
     * @return Boolean
     */
    Boolean expire(String key, long time);

    /**
     * 获取过期时间
     *
     * @param key key
     * @return long 单位秒
     */
    Long getExpire(String key);

    /**
     * 判断是否有该属性
     *
     * @param key key
     * @return Boolean
     */
    Boolean hasKey(String key);

    /**
     * 按 delta 递增
     * <p>
     * value = value + delta
     *
     * @param key   key
     * @param delta 值
     * @return Long 操作后的值
     */
    Long incr(String key, long delta);

    /**
     * 按 delta 递减
     * <p>
     * value = value - delta
     *
     * @param key   key
     * @param delta 值
     * @return Long 操作后的值
     */
    Long decr(String key, long delta);

    /**
     * 获取Hash结构中的属性
     *
     * @param key     key
     * @param hashKey hashKey
     * @return Object
     */
    Object hGet(String key, String hashKey);

    /**
     * 向Hash结构中放入一个属性
     *
     * @param key     key
     * @param hashKey hashKey
     * @param value   value
     * @param time    存活时间 单位秒
     * @return Boolean
     */
    Boolean hSet(String key, String hashKey, Object value, long time);

    /**
     * 向Hash结构中放入一个属性 永久
     *
     * @param key     key
     * @param hashKey hashKey
     * @param value   value
     */
    void hSet(String key, String hashKey, Object value);

    /**
     * 直接获取整个Hash结构
     *
     * @param key key
     * @return Map<Object, Object>
     */
    Map<Object, Object> hGetAll(String key);

    /**
     * 直接设置整个Hash结构
     *
     * @param key  key
     * @param map  map
     * @param time 存活时间 单位秒
     * @return Boolean
     */
    Boolean hSetAll(String key, Map<String, Object> map, long time);

    /**
     * 直接设置整个Hash结构
     *
     * @param key key
     * @param map map
     */
    void hSetAll(String key, Map<String, ?> map);

    /**
     * 删除Hash结构中的属性
     *
     * @param key     key
     * @param hashKey hashKey
     */
    void hDel(String key, Object... hashKey);

    /**
     * 判断Hash结构中是否有该属性
     *
     * @param key     key
     * @param hashKey hashKey
     * @return Boolean
     */
    Boolean hHasKey(String key, String hashKey);

    /**
     * Hash结构中属性递增
     *
     * @param key     key
     * @param hashKey hashKey
     * @param delta   数值
     * @return 操作后最终的值
     */
    Long hIncr(String key, String hashKey, Long delta);

    /**
     * Hash结构中属性递减
     *
     * @param key     key
     * @param hashKey hashKey
     * @param delta   数值
     * @return 操作后最终的值
     */
    Long hDecr(String key, String hashKey, Long delta);

    /**
     * 获取Set结构
     *
     * @param key key
     * @return Set<Object>
     */
    Set<Object> sMembers(String key);

    /**
     * 向Set结构中添加属性
     *
     * @param key    key
     * @param values values
     * @return 被添加到集合中的新元素的数量，不包括被忽略的元素
     */
    Long sAdd(String key, Object... values);

    /**
     * 向Set结构中添加属性
     *
     * @param key    key
     * @param time   存活时间 单位秒
     * @param values values
     * @return 被添加到集合中的新元素的数量，不包括被忽略的元素
     */
    Long sAdd(String key, long time, Object... values);

    /**
     * 是否为Set中的属性
     *
     * @param key   key
     * @param value value
     * @return Boolean
     */
    Boolean sIsMember(String key, Object value);

    /**
     * 获取Set结构的长度
     *
     * @param key key
     * @return Set结构的长度
     */
    Long sSize(String key);

    /**
     * 删除Set结构中的属性
     *
     * @param key    key
     * @param values values
     * @return 被成功移除的元素的数量，不包括被忽略的元素
     */
    Long sRemove(String key, Object... values);

    /**
     * 获取List结构中的属性
     *
     * @param key   key
     * @param start 开始索引
     * @param end   结束索引
     * @return List<Object>
     */
    List<Object> lRange(String key, long start, long end);

    /**
     * 获取List结构的长度
     *
     * @param key key
     * @return list.size
     */
    Long lSize(String key);

    /**
     * 根据索引获取List中的属性
     *
     * @param key   key
     * @param index 索引
     * @return Object
     */
    Object lIndex(String key, long index);

    /**
     * 向List结构中添加属性
     *
     * @param key   key
     * @param value value
     * @return 执行命令后，列表的长度
     */
    Long lPush(String key, Object value);

    /**
     * 向List结构中添加属性
     *
     * @param key   key
     * @param value value
     * @param time  存活时间 单位秒
     * @return 执行命令后，列表的长度
     */
    Long lPush(String key, Object value, long time);

    /**
     * 向List结构中批量添加属性
     *
     * @param key    key
     * @param values values
     * @return 执行命令后，列表的长度
     */
    Long lPushAll(String key, Object... values);

    /**
     * 向List结构中批量添加属性
     *
     * @param key    key
     * @param time   存活时间 单位秒
     * @param values values
     * @return 执行命令后，列表的长度
     */
    Long lPushAll(String key, Long time, Object... values);

    /**
     * 从List结构中移除属性
     *
     * @param key   key
     * @param count 数量
     *              count > 0 : 从表头开始向表尾搜索，移除与 VALUE 相等的元素，数量为 COUNT 。
     *              count < 0 : 从表尾开始向表头搜索，移除与 VALUE 相等的元素，数量为 COUNT 的绝对值。
     *              count = 0 : 移除表中所有与 VALUE 相等的值。
     * @param value value
     * @return 被移除元素的数量
     */
    Long lRemove(String key, long count, Object value);


    /**
     * 模糊查询所有key
     *
     * @param key key
     * @return keys
     */
    Collection<String> getKeys(String key);

    /**
     * get object
     * @param key key
     * @param clazz clazz
     * @param <T> T
     * @return clazz
     */
    <T> T getObject(String key, Class<T> clazz);


    /**
     * get list
     *
     * @param key key
     * @param clazz clazz
     * @param <T> T
     * @return // List<clazz>
     */
    <T> List<T> getObjectList(String key, Class<T> clazz);
}
